package org.gwt.mosaic.desktop.client;

import org.gwt.mosaic.application.client.Application;
import org.gwt.mosaic.core.client.DOM;
import org.gwt.mosaic.core.client.Dimension;
import org.gwt.mosaic.pagebus.client.PageBus;
import org.gwt.mosaic.ui.client.Caption;
import org.gwt.mosaic.ui.client.HTML;
import org.gwt.mosaic.ui.client.ImageButton;
import org.gwt.mosaic.ui.client.StackLayoutPanel;
import org.gwt.mosaic.ui.client.WindowPanel;
import org.gwt.mosaic.ui.client.Caption.CaptionRegion;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.google.gwt.user.client.ui.Frame;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeImages;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.Widget;

public class ControlPanel extends WindowPanel {

  public interface MyTreeImages extends TreeImages {
    /**
     * An image indicating a leaf.
     * 
     * @return a prototype of this image
     */
    @Resource("noimage.png")
    AbstractImagePrototype treeLeaf();
  }

  private static ControlPanel controlPanel;

  public static final ControlPanel get() {
    if (controlPanel == null) {
      controlPanel = new ControlPanel();
    }
    return controlPanel;
  }

  private ControlPanel() {
    super(((GwtDE) Application.getInstance()).getDesktopPanel(),
        "Control Panel", true, true);

    getDesktopPanel().setDesktopManager(new GwtDEDesktopManager());

    getHeader().add(GwtDE.IMAGES.gears().createImage());

    setWidget(createContent());

    setAnimationEnabled(true);
    setPixelSize(200, 384);
  }

  private Widget createContent() {
    StackLayoutPanel stackPanel = new StackLayoutPanel();

    stackPanel.add(createTreePanel(), "Web Sites", true);
    stackPanel.getCaption(0).add(GwtDE.IMAGES.star().createImage());

    stackPanel.add(new HTML("<i>News</i>"), "News", true);
    stackPanel.getCaption(1).add(GwtDE.IMAGES.news().createImage());

    stackPanel.add(new HTML("<i>Tools</i>"), "Tools", true);
    stackPanel.getCaption(2).add(GwtDE.IMAGES.tools().createImage());

    stackPanel.showStack(0);

    return stackPanel;
  }

  private void addMaximizeButton(final WindowPanel windowPanel,
      CaptionRegion captionRegion) {
    final ImageButton maximizeBtn = new ImageButton(
        Caption.IMAGES.windowMaximize());
    maximizeBtn.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        if (windowPanel.getWindowState() == WindowState.MAXIMIZED) {
          windowPanel.setWindowState(WindowState.NORMAL);
        } else {
          windowPanel.setWindowState(WindowState.MAXIMIZED);
        }
      }
    });
    windowPanel.addWindowStateListener(new WindowStateListener() {
      public void onWindowStateChange(WindowPanel sender,
          WindowState oldWindowState, WindowState newWindowState) {
        if (newWindowState == WindowState.MAXIMIZED) {
          maximizeBtn.setImage(Caption.IMAGES.windowRestore().createImage());
        } else {
          maximizeBtn.setImage(Caption.IMAGES.windowMaximize().createImage());
        }

      }
    });
    windowPanel.getHeader().add(maximizeBtn, captionRegion);
  }

  private void addMinimizeButton(final WindowPanel windowPanel,
      CaptionRegion captionRegion) {
    final ImageButton minimizeBtn = new ImageButton(
        Caption.IMAGES.windowMinimize());
    minimizeBtn.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        windowPanel.setWindowState(WindowState.MINIMIZED);
      }
    });
    windowPanel.getHeader().add(minimizeBtn, captionRegion);
  }

  private Widget createTreePanel() {
    ScrollPanel scrollPanel = new ScrollPanel();
    scrollPanel.getElement().getStyle().setProperty("background", "#fff");

    Tree mainMenu = new Tree((TreeImages) GWT.create(MyTreeImages.class));
    scrollPanel.add(mainMenu);

    mainMenu.setAnimationEnabled(true);
    mainMenu.addSelectionHandler(new SelectionHandler<TreeItem>() {
      public void onSelection(SelectionEvent<TreeItem> event) {
        String displayName = DOM.getElementProperty(
            event.getSelectedItem().getElement(), "displayName");
        String url = DOM.getElementProperty(
            event.getSelectedItem().getElement(), "url");

        if (displayName == null || url == null) {
          return;
        }

        final Frame frame = new Frame(url);
        frame.getElement().getStyle().setProperty("border", "none");

        WindowPanel w = new WindowPanel(getDesktopPanel(), displayName, true,
            false);
        w.setWidget(frame);

        w.getHeader().add(GwtDE.IMAGES.star().createImage());

        addMaximizeButton(w, CaptionRegion.RIGHT);
        addMinimizeButton(w, CaptionRegion.RIGHT);

        final ImageButton refreshBtn = new ImageButton(
            Caption.IMAGES.toolRefresh());
        refreshBtn.addClickHandler(new ClickHandler() {
          public void onClick(ClickEvent event) {
            frame.setUrl(frame.getUrl());
          }
        });
        w.getHeader().add(refreshBtn, CaptionRegion.RIGHT);

        w.setAnimationEnabled(true);
        // w.setHideContentOnMove(false);

        Dimension box = DOM.getClientSize(getDesktopPanel().getElement());
        w.setPixelSize(Math.min(1024, box.width), Math.min(480, box.height));

        w.center();
        
        PageBus.publish("gwtde.open", displayName);
      }
    });

    TreeItem catGwtMosaic = mainMenu.addItem("GWT Mosaic");
    setupMainMenuOption(catGwtMosaic, "Homepage",
        "http://code.google.com/p/gwt-mosaic/", GwtDE.IMAGES.star());
    setupMainMenuOption(catGwtMosaic, "Showcase",
        "http://69.20.122.77/gwt-mosaic-current/Showcase.html", GwtDE.IMAGES.star());
    setupMainMenuOption(catGwtMosaic, "Address Book",
        "http://69.20.122.77:8880/addressbook/", GwtDE.IMAGES.star());
    TreeItem catGoogle = mainMenu.addItem("Google");
    setupMainMenuOption(catGoogle, "Google Search", "http://www.google.com",
        GwtDE.IMAGES.star());
    setupMainMenuOption(catGoogle, "Google Calendar",
        "http://www.google.com/calendar/render", GwtDE.IMAGES.star());
    setupMainMenuOption(catGoogle, "Google News", "http://news.google.com/",
        GwtDE.IMAGES.star());
    setupMainMenuOption(catGoogle, "Blogger", "http://www.blogger.com/home",
        GwtDE.IMAGES.star());

    TreeItem catEntertaiment = mainMenu.addItem("Entertaiment");
    setupMainMenuOption(catEntertaiment, "iDesktop.tv",
        "http://www.idesktop.tv", GwtDE.IMAGES.star());

    TreeItem catEducation = mainMenu.addItem("Education");
    setupMainMenuOption(catEducation, "Education", "http://www.wikipedia.org",
        GwtDE.IMAGES.star());

    return scrollPanel;
  }

  private void setupMainMenuOption(TreeItem parent, String displayName,
      String url, AbstractImagePrototype image) {
    // Create the TreeItem
    TreeItem option = parent.addItem(image.getHTML() + " " + displayName);

    DOM.setElementProperty(option.getElement(), "displayName", displayName);
    DOM.setElementProperty(option.getElement(), "url", url);
  }

}
